﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using WifiChannel;

namespace BiomedicaLib.communication.channels.Source
{
    /// <summary>
    /// This class will represent the UDP sender device,inherited from ISource
    /// </summary>
    public class UDP 
    {
        #region local declerations
        UdpClient reciver,sender;
        
        
        Int32 Remot_port;
        IPEndPoint RemoteIpEndPoint;
        IPEndPoint end_point = null;
        #endregion
        /// <summary>
        /// A flag will trigger thge stop of the sens loop,stop the loop set to true
        /// </summary>
        public Boolean Stop { set; get; }
        /// <summary>
        /// This parameter will hold the recived massage, the user will grab the data using this proparty
        /// </summary>
        public String IncmeMSg { set; get; }
        /// <summary>
        /// Deinitailizing the source
        /// </summary>
        public void Deinitialize()
        {
            reciver.Close();
            sender.Close();
        }
       
        /// <summary>
        /// Initalize Connection to port
        /// </summary>
        /// <param name="port">Listing Port</param>
        /// <param name="port_out">Reciving port</param>
        public void Initilize(int port,int port_out)
        {
            try
            {
                sender = new UdpClient(port);
                reciver = new UdpClient(port_out);
            }
            catch (Exception err)
            {

            }


            
        }

       
        /// <summary>
        /// This function will start listing procedure 
        /// </summary>
        public void Listin()
        {
          reciver.BeginReceive(new AsyncCallback(PacketRecived),new UDPState());
        }

        /// <summary>
        /// Handle the sens ended event, this eventv handler must be set befor using any thing else
        /// 
        /// </summary>
        public event EventHandler<SensingFinishedEventHandlerArg> SensEnded;
        /// <summary>
        /// THe Async function that will revive the incomeing packets
        /// </summary>
        /// <param name="ar"></param>
        private void PacketRecived(IAsyncResult ar)
        {
            try
            {
                IPPacketInformation packetInfo;
                Socket sock = (Socket)ar.AsyncState;
                SocketFlags flags = SocketFlags.None;
                EndPoint remoteEnd = new IPEndPoint(IPAddress.Any, 0);
                sock.EndReceiveMessageFrom(ar, ref flags, ref remoteEnd, out packetInfo);
                Byte[] receiveBytes = reciver.EndReceive(ar, ref end_point);
                    IncmeMSg = Encoding.ASCII.GetString(receiveBytes);
                SensEnded(this, new SensingFinishedEventHandlerArg(IncmeMSg));
                Remot_IP = packetInfo.Address;
                Listin();
            }
            catch (Exception err)
            {
                System.Diagnostics.Trace.WriteLine(err.Message);
            }
        }

        internal void SendRequest(string Code)
        {

            sender = new UdpClient();
            sender.Connect(end_point.Address, 4444);
                byte[] b = new Byte[Code.Length];
                b = System.Text.ASCIIEncoding.ASCII.GetBytes(Code);
                sender.Send(b, b.Length);
                sender.Close();
           
        }

        public IPAddress Remot_IP { get; set; }
    }
    /// <summary>
    /// The Object that will hold the information when recived data is triggered
    /// </summary>
    public class UDPState : Object
    {
        /// <summary>
        /// Hold the reciver address
        /// </summary>
        public String address { set; get; }
        /// <summary>
        /// Hold the reciving port
        /// </summary>
        public Int32 port { set; get; }
    }
    public class UdpState
    {

        public IPEndPoint e;
        public UdpClient u;
    }


}
